package com.ruoyi.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.jnxx.task.domain.OkrStaff;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.domain.TRequestForm;
import com.ruoyi.pojo.dto.*;
import com.ruoyi.pojo.response.AdminApprovalResp;
import com.ruoyi.pojo.response.UserApprovalResp;
import com.ruoyi.pojo.tools.ApprovalTool;
import com.ruoyi.service.ITRequestFormService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 申请表Controller
 * 
 * @author mzr
 * @date 2023-12-11
 */
@RestController
@Slf4j
@RequestMapping("/system/form")
public class TRequestFormController extends BaseController
{
    @Autowired
    private ITRequestFormService tRequestFormService;
    @Autowired
    private ApprovalTool approvalTool;
    /**
     * 查询申请表列表
     */
    @PreAuthorize("@ss.hasPermi('system:form:list')")
    @GetMapping("/list")
    public TableDataInfo list(TRequestForm tRequestForm)
    {
        startPage();
        List<TRequestForm> list = tRequestFormService.selectTRequestFormList(tRequestForm);
        return getDataTable(list);
    }

    /**
     * 导出申请表列表
     */
    @PreAuthorize("@ss.hasPermi('system:form:export')")
    @Log(title = "申请表", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, ExportRequestFromDto exportRequestFromDto) throws IOException {
        System.out.println("请求参数"+exportRequestFromDto);

        DateTimeFormatter dtf=DateTimeFormatter.ofPattern("yyyyMMddHHmms");
        String filename=dtf.format(LocalDateTime.now());
        response.setContentType("application/json.ms-exce");
        response.setCharacterEncoding("utf-8");
        response.addHeader("Content-Disposition","filename="+filename+".xlsx");

        List<HashMap<String,Object>> list = tRequestFormService.selectTRequestFormToExport(exportRequestFromDto);
        List<List<Object>> dataList = new ArrayList<>();
        List<Object> headers = null; // 初始化 headers 变量
        if (!list.isEmpty()) {
            Set<String> keys = list.get(0).keySet();
            headers = new ArrayList<>(keys); // 设置表头
            for (HashMap<String, Object> hashMap : list) {
                List<Object> rowData = new ArrayList<>();
                for (Object key : headers) {
                    rowData.add(hashMap.getOrDefault(String.valueOf(key), "")); // 使用 getOrDefault 防止 NullPointerException
                }
                dataList.add(rowData);
            }
        }
        List<List<String>> headList = new ArrayList<>();
        if (headers != null) {
            for (Object header : headers) {
                headList.add(Collections.singletonList(String.valueOf(header)));
            }
            try (OutputStream outputStream = response.getOutputStream()) {
                EasyExcel.write(outputStream)
                        .head(headList) // 设置表头
                        .sheet("Sheet1")
                        .doWrite(dataList); // 写入数据列表
            }
        } else {
            response.getWriter().write("没有数据可导出");
        }
    }

    /**
     * 获取申请表详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:form:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(tRequestFormService.selectTRequestFormById(id));
    }

    /**
     * 新增申请表
     */
    @PreAuthorize("@ss.hasPermi('system:form:add')")
    @Log(title = "申请表", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody TRequestForm tRequestForm)
    {
        return toAjax(tRequestFormService.insertTRequestForm(tRequestForm));
    }

    /**
     * 修改申请表
     */
    @PreAuthorize("@ss.hasPermi('system:form:edit')")
    @Log(title = "申请表", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody TRequestForm tRequestForm)
    {
        return toAjax(tRequestFormService.updateTRequestForm(tRequestForm));
    }

    /**
     * 删除申请表
     */
    @PreAuthorize("@ss.hasPermi('system:form:remove')")
    @Log(title = "申请表", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(tRequestFormService.deleteTRequestFormByIds(ids));
    }

    /*提交审批*/
    @PostMapping("/pushApproval")
    public AjaxResult submitForApproval(@RequestBody FromDto fromDto, HttpServletRequest request){
        //保存审批表单 - 保存审批，保存审批详情，保存审批流程
        //获取到当前用户
       log.info("提交审批请求参数："+JSON.toJSONString(fromDto)+"请求头:"+request.getHeader("token"));
        String token = request.getHeader("token");
        if (token==null){
            throw new GlobalException("未获取到当前用户的授权信息");
        }
        Long userId = tokenAnalyze(token);//解析token
        //Long userId = 20L;
        log.info("当前用户:"+userId);
        boolean b = tRequestFormService.pushApproval(fromDto,userId);
        return toAjax(b);
    }

    /*通过审批*/
    @PostMapping("/approveApproval")
    public AjaxResult approveApproval(@RequestBody Map<String,String> map, HttpServletRequest request) {
            //查询申请表明细 - 保存审批记录 - 添加审批次数
            log.info("通过审批接口接收参数："+JSON.toJSONString(map));
            String token = request.getHeader("token");
            log.info("用户token："+JSON.toJSONString(token));
            if (token==null){
                throw new GlobalException("未获取到用户信息");
            }
            Long userId = tokenAnalyze(token);//解析token
            String fromId = map.get("FromId");
            String auditRemark = map.get("auditRemark");//审批通过备注
            String files = map.get("files");
            log.info("用户id："+userId);
            boolean b = tRequestFormService.approveApproval(auditRemark,Long.parseLong(fromId),userId,files);
            return toAjax(b);

    }
    /*审批单驳回*/ //chUpsAdPa  chDosAdpa
    @PostMapping("/rejectApproval")
    public AjaxResult rejectApproval(@RequestBody HashMap<String,Object> rejectDto, HttpServletRequest request){

           //保存审批表单 - 保存审批，保存审批详情，保存审批流程
           log.info("驳回审批接口接收参数："+JSON.toJSONString(rejectDto));
           String token = request.getHeader("token");
           if (token==null){
               throw new GlobalException("未获取到用户信息");
           }
           Long userId = tokenAnalyze(token);//解析token
           log.info("用户id："+userId);
           boolean b = tRequestFormService.rejectApproval(rejectDto,userId);
           return toAjax(b);

    }


    /*审批请求单个查询 */
    @GetMapping("/queryApproval/{FromId}")
    public AjaxResult queryApproval(@PathVariable("FromId") Long FromId){
        //查询申请表明细 - 保存审批记录 - 添加审批次数
        //Long userId = 9L; //获取到当前用户的信息 id

        ApprovalDto approvalDto = tRequestFormService.queryApproval(FromId);
        log.info("审批单单个查询"+JSON.toJSONString(approvalDto));

        return success(approvalDto);
    }

    /*审批请求单个查询，给若依后台表单使用 */
    @GetMapping("/queryApprovalForFORM/{FromId}")
    public AjaxResult queryApprovalForFORM(@PathVariable("FromId") Long FromId){
        //查询申请表明细 - 保存审批记录 - 添加审批次数
        //Long userId = 14L; //获取到当前用户的信息 id

        ApprovalDto approvalDto = tRequestFormService.queryApproval(FromId);
        ApprovalDto approvalTmp = tRequestFormService.selectAllUser(FromId);
        String approvalUsername = approvalTmp.getApprovalUsername();
        String copyUsername = approvalTmp.getCopyUsername();
        approvalDto.setApprovalUsername(approvalUsername);
        approvalDto.setCopyUsername(copyUsername);
        return success(approvalDto);
    }

    /** 审批状态 0-未处理  1-已处理   2 - 已驳回  3-协同处理 4-协同驳回  */
    /*PENDING  PROCESSED  REJECTED  COPY  search*/
    /*查询管理员审核记录 - 新*/
    @PostMapping("/queryApprovalRecord")
    public AjaxResult queryApprovalPassRecord(@RequestBody AdminApprovalRecord map,HttpServletRequest request) {
        String keyword = map.getKeyword();
        String status = map.getStatus();
        System.out.println("接收参数"+map);
        String startTime = map.getStartTime();
        String endTime = map.getEndTime();

        System.out.println("接收参数"+map);
        String token = request.getHeader("token");
        System.out.println("用户token"+token);
        if (token==null){
            throw new GlobalException("未获取到用户信息");
        }
        Long userId = tokenAnalyze(token);//解析token
        //Long userId =46L;
        Integer statusO = null;
        Integer statusT = null;

        if ("PENDING".equals(status)){
            statusO = 0;
            statusT = 0;
        }else if ("PROCESSED".equals(status)){
            statusO = 1;
            statusT = 3;
        }else if ("REJECTED".equals(status)){
            statusO = 2;
            statusT = 4;
        }else if ("COPY".equals(status)){
            return success(tRequestFormService.queryApprovalCopyRecord(keyword,userId,startTime,endTime));
        }else{
            return success(new ArrayList<AdminApprovalResp>());
        }
        return success(tRequestFormService.queryApprovalRecord(keyword,userId,statusO,statusT,startTime,endTime));
    }

    /*查询用户所有提交审批记录 -新*/
    @PostMapping("/queryUserApprovalRecord")
    public AjaxResult queryUserApprovalRecord(@RequestBody UserApprovalRecordDto recordDto,HttpServletRequest request) {
        //查询申请表明细 - 保存审批记录 - 添加审批次数
        log.info("参数"+JSON.toJSONString(recordDto));
        String formName = recordDto.getFormName();
        String keyword = recordDto.getKeyword();
        String startTime = recordDto.getStartTime();
        String endTime = recordDto.getEndTime();
        String token = request.getHeader("token");
        if (token==null){
            throw new GlobalException("未获取到用户信息");
        }
        Long userId = tokenAnalyze(token);//解析token
        //Long userId = 14L;

        List<UserApprovalResp> approvalRecordDtos = tRequestFormService.queryUserApprovalRecord(keyword,userId,formName,startTime,endTime);
        return success(approvalRecordDtos);
    }

    /*审批提醒再推送*/
    @PostMapping("/approvalReminder")
    public AjaxResult approvalReminder(@RequestBody Map<String,String> map) {
            //查询申请表明细 - 保存审批记录 - 添加审批次数
            log.info("审批提醒再推送："+JSON.toJSONString(map));
            String fromId = map.get("FromId");
            boolean b = approvalTool.approvalReminder(fromId);
            return success(b);
    }

    /*审批单再提交*/
    @PostMapping("/pushApprovalAgain")
    public AjaxResult pushApprovalAgain(@RequestBody PushApprovalAgainDto data, HttpServletRequest request) {
        //查询申请表明细 - 保存审批记录 - 添加审批次数
        log.info("审批单再提交："+JSON.toJSONString(data));
        String token = request.getHeader("token");
        if (token==null){
            throw new GlobalException("未获取到用户信息");
        }
        Long userId = tokenAnalyze(token);//解析token
        boolean b = tRequestFormService.pushApprovalAgain(data,userId);
        return success(b);
    }

    /*撤回审批单  -增加字段撤回备注*/
    @PostMapping("/revocationApprovalForm")
    public AjaxResult revocationApprovalForm(@RequestBody RevocationApprovalFormDto data, HttpServletRequest request) {
        String token = request.getHeader("token");
        if (token==null){
            throw new GlobalException("未获取到用户信息");
        }
        Long userId = tokenAnalyze(token);//解析token
        //Long userId = 20L;
        boolean b = tRequestFormService.revocationApprovalPathForm(userId,data);
        return success(b);
    }




    /*token解析*/
    private Long tokenAnalyze(String token){
        try {
            String decode = URLDecoder.decode(token, "UTF-8");
            OkrStaff staff = JSONObject.parseObject(decode, OkrStaff.class);
            return staff.getId();
        }catch (Exception e) {
            log.error("解析token异常，token:"+token);
            throw new GlobalException("系统异常，用户身份解析失败！");
        }

    }

}
